package admin_menus

import (
	"gitee.com/theegg/go-brick/app/model"
	"gitee.com/theegg/go-brick/app/model/admin/admin_role_menus"
	"gitee.com/theegg/go-brick/app/service/app"
)

// 查询参数
type AdminMenuQueryParams struct {
	PageSize  string `form:"page_size" json:"page_size"  binding:"gte=0,lte=100" label:"每页数量"`
	PageIndex string `form:"page_index" json:"page_index"  binding:"gte=0,lte=99999" label:"当前页数"`
	Route     string `form:"route" json:"route"  binding:"" label:"路由"`
}

// add 参数
type AdminMenusAddParams struct {
	Route string `form:"route" binding:"" label:"路由"`
	Sort  int    `form:"sort" label:"排序"`
	Title string `form:"title"  binding:"required,min=2,max=32" label:"标题"`
	Icon  string `form:"icon" label:"图标"`
	Path  string `form:"path"  binding:"required" label:"路径"`
	Pid   int64  `form:"pid" binding:"" label:"上级菜单"`
	Level int32  `form:"level"  binding:"" label:"等级"`
}

// 返回的数据结构 == checkbox
type MenusCheckData struct {
	Id       int64             `json:"id"`
	Label    string            `json:"label"`
	Children []*MenusCheckData `json:"children"`
}

// 返回的数据结构 列表树
type MenuListData struct {
	Id       int64
	Route    string
	Sort     int
	Title    string
	Icon     string
	Path     string
	Status   int
	Children []*MenuListData
}

// 每个角色都拥有的menuId
var MustMenuId int64 = 100000

// 获取所有数据 无翻页 有上下级
// @param params map 参数
// @return mix
func GetDataList(params map[string]interface{}) ([]*MenuListData, error) {

	queryParams, err := model.BuildAdminQueryParam(params)
	if err != nil {
		return nil, err
	}

	items := make([]*AdminMenus, 0)
	query := app.Db().Desc("sort")

	// 路由
	if v, ok := queryParams.Params["route"]; ok && v != "" {
		query.And("route like ?", "%"+queryParams.Params["route"].(string)+"%")
	}

	// 标题
	if v, ok := queryParams.Params["title"]; ok && v != "" {
		query.And("title like ?", "%"+queryParams.Params["title"].(string)+"%")
	}

	// 查询多条数据
	errQuery := query.Asc("sort").Find(&items)
	if errQuery != nil {
		return nil, errQuery
	}

	returnData := BuildMenuListTree(items, 0, 2)
	return returnData, nil
}

// 获取数据 通过ID
func GetItemById(id int64) (*AdminMenus, error) {
	item := new(AdminMenus)

	has, err := app.Db().ID(id).Get(item)

	if err != nil {
		return nil, err
	} else {
		if !has {
			return item, nil
		}
	}

	return item, nil
}

// 添加 / 更新 管理菜单
// 不用反射合并结构体
func (am *AdminMenus) AddOrUpdateAdminMenu(params AdminMenusAddParams) (*AdminMenus, error) {

	var affected int64
	var errInsert error

	// 如果指定了上级 检测PID
	parentMenu := new(AdminMenus)
	if params.Pid > 0 {
		has, errParent := app.Db().ID(params.Pid).Get(parentMenu)
		if errParent != nil {
			return nil, app.NewError(errParent)
		}

		if !has {
			return nil, app.NewError("对不起, PID无效")
		}
	}

	if am != nil && am.Id > 0 {
		// 更新数据
		am.Route = params.Route
		am.Title = params.Title
		am.Sort = params.Sort
		am.Path = params.Path
		am.Icon = params.Icon

		affected, errInsert = app.Db().ID(am.Id).Update(am)

		if errInsert != nil {
			return nil, app.NewError(errInsert)
		}

		if affected != 1 {
			return nil, app.NewError("更新错误")
		}
	} else {
		// 计算上一个菜单的ID
		lastMenu := new(AdminMenus)
		has, errLast := app.Db().Where("pid = ?", params.Pid).Desc("id").Get(lastMenu)
		if errLast != nil {
			return nil, app.NewError(errLast)
		}

		var newId int64 = 100000
		var sort int = 0
		if has {
			if params.Pid > 0 {
				newId = lastMenu.Id + 1000
			} else {
				newId = lastMenu.Id + 100000
			}

			sort = lastMenu.Sort + 1
		} else {
			if params.Pid > 0 {
				newId = params.Pid + 1000
				sort = 0
			}
		}

		// 插入数据
		am.Id = newId
		am.Route = params.Route
		am.Title = params.Title
		am.Sort = sort
		am.Path = params.Path
		am.Icon = params.Icon
		am.Pid = params.Pid
		am.Status = 1

		affected, errInsert = app.Db().Insert(am)

		if errInsert != nil {
			return nil, app.NewError(errInsert)
		}

		if affected != 1 {
			return nil, app.NewError("新增菜单错误(0x001)")
		}
	}

	return am, nil
}

// 删除菜单
// 1. 删除菜单
// 2. 删除下级菜单
// 3. 删除用户角色分配的菜单
func DeleteMenu(menuId int64) (bool, error) {

	// 1. 获取所有需要删除的menuId
	var ids []int64
	errIds := app.Db().Table("admin_menus").Where("pid = ?", menuId).Or("id = ?", menuId).Cols("id").Find(&ids)
	if errIds != nil {
		return false, app.NewError(errIds)
	}

	// 2 事物删除
	session := app.Db().NewSession()
	defer session.Close()
	errSb := session.Begin()
	if errSb != nil {
		return false, app.NewError(errSb)
	}

	// == 删除 菜单
	item := new(AdminMenus)
	_, errMenu := session.In("id", ids).Delete(item)
	if errMenu != nil {
		session.Rollback()
		return false, app.NewError(errMenu)
	}

	// == 删除 角色帮顶菜单
	roleMenus := new(admin_role_menus.AdminRoleMenus)
	_, errRoleMenu := session.In("id", ids).Delete(roleMenus)
	if errRoleMenu != nil {
		session.Rollback()
		return false, app.NewError(errRoleMenu)
	}

	// 提交
	errCommit := session.Commit()
	if errCommit != nil {
		return false, app.NewError(errCommit)
	}

	return true, nil
}

// 获取所有的菜单
func (am AdminMenus) GetAllAdminMenu() (map[int64]AdminMenus, error) {
	items := make(map[int64]AdminMenus)

	err := app.Db().Where("status = ?", true).Find(&items)
	if err != nil {
		return items, err
	}

	return items, err
}

// @title BuildMenusTree
// @description 构建山下级关系树
func BuildMenuCheckDataTree(sourceData map[int64]*AdminMenus, pid int64, levelArgs ...int) []*MenusCheckData {
	deep := 3
	if len(levelArgs) > 0 {
		deep = levelArgs[0]
	}

	deep--

	buildData := make([]*MenusCheckData, 0)

	for _, item := range sourceData {
		if item.Pid == pid {
			data := MenusCheckData{
				Id:       item.Id,
				Label:    item.Title,
				Children: make([]*MenusCheckData, 0),
			}

			if deep > 0 {
				data.Children = BuildMenuCheckDataTree(sourceData, item.Id, deep)
			}

			buildData = append(buildData, &data)
		}
	}

	return buildData
}

// @title BuildMenuListTree
// @description 关系树　列表页使用
func BuildMenuListTree(sourceData []*AdminMenus, pid int64, levelArgs ...int) []*MenuListData {
	deep := 3
	if len(levelArgs) > 0 {
		deep = levelArgs[0]
	}

	deep--

	buildData := make([]*MenuListData, 0)

	for _, item := range sourceData {
		if item.Pid == pid {
			data := MenuListData{
				Id:       item.Id,
				Title:    item.Title,
				Route:    item.Route,
				Sort:     item.Sort,
				Path:     item.Path,
				Icon:     item.Icon,
				Status:   item.Status,
				Children: make([]*MenuListData, 0),
			}

			if deep > 0 {
				data.Children = BuildMenuListTree(sourceData, item.Id, deep)
			}

			buildData = append(buildData, &data)
		}
	}

	return buildData
}

// @title GetAdminMenusByRoleIdFromDb
// @description 从数据库获取所有的  指定管理角色　分配的菜单, 超级管理员　取出全部
// @return map[int64]*AdminMenus
func GetAdminMenusByRoleIdFromDb(roleId int64, superRoleOptions ...bool) (map[int64]*AdminMenus, error) {
	isSupperRole := false
	if len(superRoleOptions) > 0 && superRoleOptions[0] {
		isSupperRole = true
	}

	adminMenus := make(map[int64]*AdminMenus)

	if !isSupperRole {
		adminRoleMenus := make(map[int64]*admin_role_menus.AdminRoleMenus)
		err := app.Db().Where("role_id = ?", roleId).Find(&adminRoleMenus)
		if err != nil {
			return nil, app.NewError(err)
		}

		// 所有的IDS
		ids := make([]int64, 0)
		for _, k := range adminRoleMenus {
			ids = append(ids, k.MenuId)
		}

		// 如果没有数据
		if len(ids) == 0 {
			return adminMenus, nil
		}

		errPer := app.Db().Asc("sort").In("id", ids).Find(&adminMenus)
		if errPer != nil {
			return nil, app.NewError(errPer)
		}
	} else {
		// 超级角色　不需要配置
		errPer := app.Db().Asc("sort").Where("status = ?", 1).Find(&adminMenus)
		if errPer != nil {
			return nil, app.NewError(errPer)
		}
	}

	return adminMenus, nil
}
